#ifndef DATA
#define DATA

#include <iostream>
#include <fstream>
#include <string>
#include "fileUtil.hpp"
#include <vector>
#include <unordered_map>

#define SERVERPATH "/server/"

namespace bucai
{
    class DataManager{
    private:
        std::string _manager_file;
        std::unordered_map<std::string, std::string> _table; //key是文件路径名，val是文件唯一标识
        
    public:
        DataManager(std::string filename) :_manager_file(filename) {
            InitLoad();
        }
        bool Split(std::string& str, const std::string& sep, std::vector<std::string>* arry) {
            auto it = str.begin();
            while (it != str.end()) {
                size_t sum = str.find(sep);
                std::string str1 = str.substr(0, sum);
                arry->push_back(str1);
                str = str.substr(sum + 1);
                it = str.begin();
            }
            return true;
        }

        bool InitLoad()
        { // 初始化程序运⾏时从⽂件读取数据

            bucai::fileUtil fu(_manager_file);
            std::string body;
            fu.GetContent(&body);

            //存储的urlkey、val是按照 ` 进行切分，按照"\n"做为分行
            std::vector<std::string> vec;
            Split(body, "\n", &vec);//先把没行的key\val切分出来
            for (auto e : vec) { //再分开key\val到_table中

                size_t num = e.find("\`");
                std::string s1 = e.substr(0, num);
                std::string s2 = e.substr(num + 1);

                _table[s1] = s2;
            }
            return true;
        }
        bool Storage(){ // 每次有信息改变则需要持久化存储⼀次

            bucai::fileUtil fu(_manager_file);
            std::string body;
            for (auto e : _table) {
                body += e.first;
                body += "`";
                body += e.second += "\n";
            }
            fu.SetContent(body);
            return true;
        }
        bool Insert(const std::string &urlkey, const std::string& val)
        {
            _table[urlkey] = val;
            Storage();
            return true;

        }
        bool Update(const std::string &urlkey, const std::string& val)
        {
            _table[urlkey] = val;
            Storage();
            return true;
        }
        bool GetOneByKey(const std::string &key, std::string* val)
        {
            auto it = _table.find(key);
            if (it == _table.end()) {
                //std::cout << "data.hpp :> GetOneByKey is false" << std::endl;
                return false;
            }
            *val = it->second;
            return true;
        }
        
        bool printTable()
        {
            for (auto e : _table) {
                std::cout << e.first << " | " << e.second << std::endl;
            }
            return true;
        }
    };
}
#endif